﻿using System;
using System.Threading;
using System.IO;
using System.Configuration;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.ServiceModel;
using SQLdbMySqlLib;
using Support;
using MySql.Data.MySqlClient;

namespace PhotoBackupWS
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://PhotoBackup.org/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
   
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class PhotoBackup : System.Web.Services.WebService
    {
        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
            //System.Configuration.
        }

        [WebMethod]
        public ObjSession connect()
        {
            Engine ee = new Engine();

            try
            {
                ObjSession objSes = ee.startSession();
                sessionCleaner();
                return objSes;
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "1");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name,e);
                throw se3;
            }
        }

        [WebMethod]
        public bool login(string sessionID, string userName , string ePassword)
        {
            try
            {
                return new Engine().login(userName, sessionID, ePassword);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "2");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            }
        }

        [WebMethod]
        public ObjData getDataObject(string sessionID, int objectID)
        {
            try
            {
                return new Engine().getDataObject(sessionID, objectID);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "3");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            }
        }

        [WebMethod]
        public void insertDataObject(string sessionID, int album, int type, string eName, string eFilesize, byte[] eRawData)
        {
            try
            {
                new Engine().insertDataObject(sessionID, type, album, eName, eFilesize, eRawData);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "4");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            } 
        }

        [WebMethod]
        public bool deleteDataObject(string sessionID, string eObjID)
        {
            try
            {
               return new Engine().deleteDataObject(sessionID, eObjID);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "5");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            } 
        }

        [WebMethod]
        public bool deleteAlbumContent(string sessionID, string eAlbumID)
        {
            try
            {
                return new Engine().deleteAlbumContent(sessionID, eAlbumID);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "6");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            }
        }

        [WebMethod]
        public void changeDataObjectName(string sessionID, string eObjectID, string eNewName )
        {
            try
            {
                new Engine().changeDataObjectName(sessionID, eObjectID, eNewName);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "7");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            }
        }

        [WebMethod]
        public void changeDataObjectAlbum(string sessionID, string eObjectID, string eNewAlbum)
        {
            try
            {
                new Engine().changeDataObjectAlbum(sessionID, eObjectID, eNewAlbum);
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error", "8");
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("Photo Backup Web Service ERROR !!!", name, e);
                throw se3;
            }
        }

        private static Thread worker;
        private EventWaitHandle blockHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
        private static ParameterizedThreadStart workerP;

        private void sessionCleaner()
        {
            if (workerP == null)
            {
                workerP = new ParameterizedThreadStart(WorkerThread);
                Thread runer = new Thread(workerP);
                runer.Start();
                EventWaitHandle.WaitAny(new WaitHandle[] { blockHandle });
            }
            else
            {
                if (worker.IsAlive == false)
                {
                    workerP = new ParameterizedThreadStart(WorkerThread);
                    Thread runer = new Thread(workerP);
                    runer.Start();
                    EventWaitHandle.WaitAny(new WaitHandle[] { blockHandle });
                }
            }
        }

        private void WorkerThread(Object prams)
        {
            blockHandle.Set();
            while (true)
            {
                sqlTimeCaller(150);
            }
        }


        private void sqlTimeCaller(int timeSec)
        {
            if (worker != Thread.CurrentThread)
            {
                worker = Thread.CurrentThread;
            }
            Thread.Sleep(TimeSpan.FromSeconds(timeSec));
            Engine ee = new Engine();
            try
            {
                ee.sessionTimeoutRemover();
            }
            catch (Exception)
            {
            }
        }






        //****************************************************************\\
        //                      T E S T   M E T H O D S                   \\
        //****************************************************************//

        


        private static Thread running;
        private EventWaitHandle latch = new EventWaitHandle(false, EventResetMode.AutoReset);
        private static ParameterizedThreadStart deli;

        [WebMethod]
        public string testGenerator()
        {
            //Generator g = new Generator();

            return new Generator().Generate(30);
        }

        [WebMethod]
        public string testLaunchAsyncThread()
        {
            if (deli == null)
            {
                deli = new ParameterizedThreadStart(testMyAsyncMethod);
                    Thread newThread = new Thread(deli);
                    newThread.Start();
                    EventWaitHandle.WaitAny(new WaitHandle[] { latch });
                    return "started";
            }
            else
            {
                if (running.IsAlive == false)
                {
                    deli = new ParameterizedThreadStart(testMyAsyncMethod);
                    Thread newThread = new Thread(deli);
                    newThread.Start();
                    EventWaitHandle.WaitAny(new WaitHandle[] { latch });
                    return "started";
                }
                else
                {
                    return "working";
                }
            }
        }



        private void testMyAsyncMethod(Object prams)
        {
            latch.Set();
            while (true)
            {
                testTimer();
            }
        }

       

        
        

        [WebMethod]
        public string testMainThread()
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            bool live = Thread.CurrentThread.IsAlive;
            return "id " + id + ". live " + live;
        }


        private void testTimer()
        {
            if (running != Thread.CurrentThread)
            {
                running = Thread.CurrentThread;
            }
            Thread.Sleep(TimeSpan.FromSeconds(5));
            MySQL sql = new MySQL();
            sql.connect("localhost", "stawiu", "dupa", "teamplay");
            DataSet dtSet = sql.select("SELECT nazwa FROM test WHERE ID = 1");
            string end = "";
            foreach (DataRow r in dtSet.Tables[0].Rows)
            {
                end = (string)r["nazwa"];
            }
            int plus = Int32.Parse(end) + 1;
            MySqlCommand cmd = new MySqlCommand();
            string SQL = "UPDATE test SET nazwa=@Name WHERE ID=1";
            cmd.CommandText = SQL;
            cmd.Parameters.AddWithValue("@Name", plus + "");
            sql.insert(cmd);
            sql.disconnect();
        }

        [WebMethod]
        public string testKiller()
        {
            if (running == null)
            {
                return "nothing to kill";
            }
            else
            {
                running.Abort();
                return "killed";
            }
        }

        

        [WebMethod]
        public string testSQLdbMySqlLibConnect()
        {
            MySQL sql = new MySQL();
            try
            {
                //sql.connect("", "", "", "");
                //sql.connect("db4free.net", "pbuser", "pbuser", "wsdb");
                sql.connect("localhost", "stawiu", "dupa", "teamplay");
            }
            catch (Exception e)
            {
                System.Xml.XmlQualifiedName name = new System.Xml.XmlQualifiedName("error","1");
                
                System.Web.Services.Protocols.SoapException se3 = new System.Web.Services.Protocols.SoapException("chuj", name , e);
                throw se3;
            }
            return "connected";
        }

        [WebMethod]
        public string testEngineTestMethod()
        {
            return new Engine().testMethod();
        }



        [WebMethod]
        public string testAesEncrypt(string PlainText)
        {
            //Aes aes = new Aes();
            byte[] KeyBytes = Aes.createKeyBytes("pass", "salty");
            return Aes.EncryptString(PlainText, KeyBytes);
        }

        [WebMethod]
        public string testAesDecrypt(string cypherText)
        {
            //Aes aes = new Aes();
            byte[] KeyBytes = Aes.createKeyBytes("pass", "salty");
            return Aes.DecryptString(cypherText, KeyBytes);
        }

        [WebMethod]
        public string testSQLdbMySqlLibSelect()
        {
            MySQL sql = new MySQL();
            sql.connect("db4free.net", "pbuser", "pbuser", "wsdb");
            DataSet dtSet = sql.select("SELECT * FROM users");

            string end = "";
            foreach (DataRow r in dtSet.Tables[0].Rows)
            {
                string temp = end;
                end = temp + r["name"] + "/";
            }

            return end;
        }

        [WebMethod]
        public void testSQLdbMySqlLibSelectPicture(int id)
        {
            MySQL sql = new MySQL();
            sql.connect("localhost", "stawiu", "dupa", "teamplay");
            DataSet dtSet = sql.select("SELECT * FROM pictures WHERE ID =" + id);


            foreach (DataRow r in dtSet.Tables[0].Rows)
            {
                Int64 FileSizeLong = (Int64)r["FileSize"];
                int FileSize = Convert.ToInt32(FileSizeLong);
                byte[] rawData = new byte[FileSize];
                rawData = (byte[])r["Data"];

                FileStream fs = new FileStream("C:/newfilefromdb.bmp", FileMode.OpenOrCreate, FileAccess.Write);
                fs.Write(rawData, 0, FileSize);
                fs.Close();
                //string temp = end;
                //end = temp + r["name"] + "/";
            }


        }



        [WebMethod]
        public string testEngineGetSession(string sessID)
        {
            Engine ee = new Engine();
            ObjWSSession wsSess = ee.getSession(sessID);
            return wsSess.DbHost + " " + wsSess.DbName + " " + wsSess.DbType;
        }

        [WebMethod]
        public string testEngineCreatePictureTable()
        {
            Engine ee = new Engine();

            ObjWSSession wsSess = ee.getSession("123456789");

            // ee.t.GetMethod("conenct");
            ee.CreatePictureTable(wsSess);
            return wsSess.DbType;
        }


        [WebMethod]
        public MySQL testSQLdbMySqlLibInsertFile(string name)
        {
            MySQL sql = new MySQL();
            sql.connect("localhost", "stawiu", "dupa", "test");

            FileStream fs = new FileStream(@"c:\" + name, FileMode.Open, FileAccess.Read);
            int FileSize = (int)fs.Length;

            byte[] rawData = new byte[FileSize];
            fs.Read(rawData, 0, FileSize);
            fs.Close();

            //FileSize = 0;
            //rawData = null;

            sql.insertDataObject(1, FileSize, rawData, name, -1);

            return sql;
        }

        [WebMethod]
        public void testEncryptDecryptFile()
        {
            FileStream fs = new FileStream(@"c:\test.bmp", FileMode.Open, FileAccess.Read);
            int FileSize = (int)fs.Length;

            byte[] rawData = new byte[FileSize];
            fs.Read(rawData, 0, FileSize);
            fs.Close();

            //Aes aes = new Aes();
            byte[] KeyBytes = Aes.createKeyBytes("pass", "dsa");
            byte[] encryptedData = Aes.Encrypt(rawData, KeyBytes);



            byte[] rawData2 = new byte[FileSize];
            rawData2 = Aes.Decrypt(encryptedData, KeyBytes);

            FileStream fs2 = new FileStream("C:/result.bmp", FileMode.OpenOrCreate, FileAccess.Write);
            fs2.Write(rawData2, 0, FileSize);
            fs2.Close();

        }

        [WebMethod]
        public ObjContent testObject()
        {
            ObjContent temp = new ObjContent();
            //temp.ErrorCode = 3;

            return temp;


        }


        private void InitializeComponent()
        {
            
        }
    }
}
